package com.wiscamp.ninechapters.challenges.domain.repositories;

import com.wiscamp.ninechapters.challenges.domain.models.Medal;
import com.wiscamp.ninechapters.challenges.domain.models.UserMedal;
import com.wiscamp.ninechapters.challenges.infrastructure.mappers.MedalMapper;
import com.wiscamp.ninechapters.challenges.infrastructure.mappers.UserMedalMapper;
import com.wiscamp.ninechapters.challenges.infrastructure.po.MedalPO;
import com.wiscamp.ninechapters.challenges.infrastructure.po.UserMedalPO;
import cube.ddd.aspect.AopDataException;
import com.wiscamp.ninechapters.common.core.CollectionHelper;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Objects;

@Repository
public class MedalsRepository {

    @Autowired
    private MedalMapper medalMapper;

    @Autowired
    private UserMedalMapper userMedalMapper;

    //region converter
    public Medal toMedal(@NotNull MedalPO po) {
        var entity = new Medal();
        BeanUtils.copyProperties(po, entity);
        return entity;
    }

    public MedalPO toMedalPO(@NotNull Medal entity) {
        var po = new MedalPO();
        BeanUtils.copyProperties(entity, po);
        return po;
    }

    public UserMedal toUserMedal(@NotNull UserMedalPO po) {
        var entity = new UserMedal();
        BeanUtils.copyProperties(po, entity);
        return entity;
    }

    public UserMedalPO toUserMedalPO(@NotNull UserMedal entity) {
        var po = new UserMedalPO();
        BeanUtils.copyProperties(entity, po);
        return po;
    }
    //endregion

    @AopDataException
    public Medal saveMedal(Medal medal) {
        var medalPO = toMedalPO(medal);
        var savedPO = medalMapper.saveAndFlush(medalPO);
        if (Objects.nonNull(savedPO))
            return toMedal(savedPO);
        return null;
    }

    @AopDataException
    public UserMedal saveUserMedal(UserMedal userMedal) {
        var userMedalPO = toUserMedalPO(userMedal);
        var savedPO = userMedalMapper.saveAndFlush(userMedalPO);
        if (Objects.nonNull(savedPO))
            return toUserMedal(savedPO);
        return null;
    }


    @AopDataException
    public Collection<Medal> getUserMedals(long userId) {
        var medalPOList = userMedalMapper.getUserMedals(userId);
        return CollectionHelper.convertToArrayList(medalPOList, this::toMedal);
    }


    @AopDataException
    public Medal getMedalByCode(String medalCode) {
        var medalPO = medalMapper.findByMedalCode(medalCode);
        if (Objects.nonNull(medalPO))
            return toMedal(medalPO);
        return null;
    }
}
